package com.ruoyi.project.system;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;

import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.system.config.AlipayConfig;
import com.ruoyi.project.system.post.service.IPostService;
import com.ruoyi.project.system.role.service.IRoleService;
import com.ruoyi.project.system.user.domain.User;
import com.ruoyi.project.system.user.service.IUserService;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @program: ruoyi
 * @description: 测试支付的接口/pay的类
 * @author: yanghua
 * @create: 2020-09-22 17:57
 **/
@RestController
@RequestMapping("/testpay")
public class PayController extends BaseController {

    private String prefix = "system/role";

    @Autowired
    private IUserService userService;
    @Autowired
    private IRoleService roleService;

    @Autowired
    private IPostService postService;

    @PostMapping("/pay")
    public void payController(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.sign_type);

        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

        //商户订单号，商户网站订单系统中唯一订单号，必填
        String out_trade_no = new String(request.getParameter("WIDout_trade_no").getBytes("ISO-8859-1"), "UTF-8");
        //付款金额，必填
        String total_amount = new String(request.getParameter("WIDtotal_amount").getBytes("ISO-8859-1"), "UTF-8");
        //订单名称，必填
        String subject = new String(request.getParameter("WIDsubject").getBytes("ISO-8859-1"), "UTF-8");
        //商品描述，可空
        String body = new String(request.getParameter("WIDbody").getBytes("ISO-8859-1"), "UTF-8");

        alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
                + "\"total_amount\":\"" + total_amount + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"body\":\"" + body + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        //若想给BizContent增加其他可选请求参数，以增加自定义超时时间参数timeout_express来举例说明
        //alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
        //		+ "\"total_amount\":\""+ total_amount +"\","
        //		+ "\"subject\":\""+ subject +"\","
        //		+ "\"body\":\""+ body +"\","
        //		+ "\"timeout_express\":\"10m\","
        //		+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        //请求参数可查阅【电脑网站支付的API文档-alipay.trade.page.pay-请求参数】章节

        //请求
        String form = "";
        try {
            form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        response.setContentType("text/html;charset=" + AlipayConfig.CHARSET);
        response.getWriter().write(form);//直接将完整的表单html输出到页面
        response.getWriter().flush();
        response.getWriter().close();
    }

    @RequestMapping("/zfbLogin")
    public String zfbLogin(HttpServletRequest request, HttpServletResponse response){

        // 获取AuthCode 等，具体可以获取哪些数据参考支付宝官方接口文档，这里只需要使用auth_code
        String authCode = request.getParameter("auth_code");
        System.out.println("authCode ==> "+authCode);
        String msg1="";
        if(StringUtils.isNotEmpty(authCode)){
            try{
                // 这些参数均被抽取出来，参数说明见博客
                AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.sign_type);

                // 通过authCode获取accessToken
                AlipaySystemOauthTokenRequest oauthTokenRequest = new AlipaySystemOauthTokenRequest();
                oauthTokenRequest.setCode(authCode);
                oauthTokenRequest.setGrantType("authorization_code");
                AlipaySystemOauthTokenResponse oauthTokenResponse = alipayClient.execute(oauthTokenRequest);
                String accessToken = oauthTokenResponse.getAccessToken();
                System.out.println("accessToken ==> "+accessToken);


                if(StringUtils.isNotEmpty(accessToken)){
                    // 根据accessToken获取用户信息
                    AlipayUserInfoShareResponse userInfoResponse = alipayClient.execute(new AlipayUserInfoShareRequest(), accessToken);
                    if (userInfoResponse.isSuccess()){

                        String body = userInfoResponse.getBody();
                        if(!StringUtils.isEmpty(body)){
                            JSONObject jsonObject = JSONObject.parseObject(body);
                            System.out.println("jsonObject = "+jsonObject);
                            JSONObject object = jsonObject.getJSONObject(AlipayConfig.ALIPAY_SYSTEM_OAUTH_TOKEN_RESPONSE);
                            System.out.println("object = "+object);
                            /*
                            用户id是唯一的，查询用户表是否有该用户，没有就添加并绑定角色
                             */
                            //1.获取id查询用户表
                            String user_id = (String)object.get("user_id");
                            System.out.println("user_id = "+user_id);
                            User user = userService.selectUserById(Long.valueOf(user_id));
                            System.out.println(user==null);
                            if (user==null){//查询为空插入
                                User user1 = new User();
                                String gender = (String)object.get("gender");//性别
                                if ("m".equals(gender)){
                                    gender="1";//女
                                }else {
                                    gender="0";//男
                                }
                                String nick_name = (String)object.get("nick_name");//昵称
                                String avatar = (String)object.get("avatar");//头像地址
                                /*
                                =======start===================缺少用户名和密码，加密盐(支付宝333333，微信444444)
                                 */
                                //根据昵称生成用户名
                                String login_name = getPinyin(nick_name + user_id.substring(user_id.length() - 4));

                                /*
                                ==========end================缺少用户名和密码，加密盐(支付宝333333，微信444444)
                                 */
                                //默认部门id是105
                                String dept_id="105";
                                //支付宝默认用户类型是01
                                String user_type="01";
                                //=========================================填充============================
                                user1.setPassword("123456");
                                //ID必须用雪花算法
                                user1.setUserId(Long.valueOf(user_id));
                                user1.setAvatar(avatar);
                                user1.setLoginDate(new Date());
                                user1.setSex(gender);
                                user1.setUserName(nick_name);
                                user1.setUserType(user_type);
                                user1.setDelFlag("0");

                                user1.setLoginName(login_name);
                                user1.setStatus("0");
                                Long[] postIds={(long)4};
                                user1.setPostIds(postIds);
                                user1.setDeptId(Long.valueOf(dept_id));
                                Long[] roleIds={(long)2};
                                user1.setRoleIds(roleIds);
                                int i = userService.insertUser2(user1);
                                if (i>0){
                                    UsernamePasswordToken token = new UsernamePasswordToken(login_name, "123456", true);
                                    Subject subject = SecurityUtils.getSubject();
                                    try
                                    {
                                        subject.login(token);
                                        //response.sendRedirect("http://121.4.239.166:8080/index");
                                        response.sendRedirect("http://baiyun.com:7777/index");
                                    }
                                    catch (AuthenticationException e)
                                    {
                                        String msg = "用户或密码错误";
                                        if (StringUtils.isNotEmpty(e.getMessage()))
                                        {
                                            msg = e.getMessage();
                                        }
                                        //response.sendRedirect("http://121.4.239.166:8080");
                                        response.sendRedirect("http://baiyun.com:7777/index");
                                    }
                                }else {
                                    //response.sendRedirect("http://121.4.239.166:8080");
                                    response.sendRedirect("http://baiyun.com:7777/index");

                                }

                            }else {
                                //查询到用户免密登录
                                UsernamePasswordToken token = new UsernamePasswordToken(user.getLoginName(), "NoPwd", true);
                                Subject subject = SecurityUtils.getSubject();

                                try
                                {
                                    subject.login(token);
                                    //response.sendRedirect("http://121.4.239.166:8080/index");
                                    response.sendRedirect("http://baiyun.com:7777/index");
                                }
                                catch (AuthenticationException e)
                                {
                                    String msg = "用户或密码错误";
                                    if (StringUtils.isNotEmpty(e.getMessage()))
                                    {
                                        msg = e.getMessage();
                                    }
                                    //response.sendRedirect("http://121.4.239.166:8080");
                                    response.sendRedirect("http://baiyun.com:7777/index");
                                }
                            }


                        }else {
                            //response.sendRedirect("http://121.4.239.166:8080");
                            response.sendRedirect("http://baiyun.com:7777/index");
                        }

                    }else{
                        msg1="无法获取用户信息";
                    }
                }else{
                    msg1="接入支付宝登录认证出现错误，无法获取到accessToken.";
                }
            }catch (Exception e){
                msg1="获取支付宝用户信息失败:"+e.getMessage();
                e.printStackTrace();
            }
        }else{
            msg1="接入支付宝登录回调方法错误，无法获取到Token.";
        }
        return msg1;
    }

    public static void main(String[] args) {
        System.out.println(getPinyin("sdsfa")); //--zhongguohong123
    }
    /**
     * @param china (字符串 汉字)
     * @return 汉字转拼音 其它字符不变
     */
    public static String getPinyin(String china){
        HanyuPinyinOutputFormat formart = new HanyuPinyinOutputFormat();
        formart.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        formart.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        formart.setVCharType(HanyuPinyinVCharType.WITH_V);
        char[] arrays = china.trim().toCharArray();
        String result = "";
        try {
            for (int i=0;i<arrays.length;i++) {
                char ti = arrays[i];
                if(Character.toString(ti).matches("[\\u4e00-\\u9fa5]")){ //匹配是否是中文
                    String[] temp = PinyinHelper.toHanyuPinyinStringArray(ti,formart);
                    result += temp[0];
                }else{
                    result += ti;
                }
            }
        } catch (BadHanyuPinyinOutputFormatCombination e) {
            e.printStackTrace();
        }

        return result;
    }
}
